#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
 * ntp 4.2.8p12  source code
 */

/* gregorian calendar date */
struct calendar {
  uint16_t year;/* year (A.D.) */
  uint16_t yearday;/* day of year, 1 = January 1 */
  uint8_t  month;/* month, 1 = January */
  uint8_t  monthday;/* day of month */
  uint8_t  hour;/* hour of day, midnight = 0 */
  uint8_t  minute;/* minute of hour */
  uint8_t  second;/* second of minute */
  uint8_t  weekday;/* 0..7, 0=Sunday */
};

int
ntpcal_get_build_date(
		      struct calendar * jd
		      )
{
  /* The C standard tells us the format of '__DATE__':
   *
   * __DATE__ The date of translation of the preprocessing
   * translation unit: a character string literal of the form "Mmm
   * dd yyyy", where the names of the months are the same as those
   * generated by the asctime function, and the first character of
   * dd is a space character if the value is less than 10. If the
   * date of translation is not available, an
   * implementation-defined valid date shall be supplied.
   *
   * __TIME__ The time of translation of the preprocessing
   * translation unit: a character string literal of the form
   * "hh:mm:ss" as in the time generated by the asctime
   * function. If the time of translation is not available, an
   * implementation-defined valid time shall be supplied.
   *
   * Note that MSVC declares DATE and TIME to be in the local time
   * zone, while neither the C standard nor the GCC docs make any
   * statement about this. As a result, we may be +/-12hrs off
   * UTC.  But for practical purposes, this should not be a
   * problem.
   *
   */
#   ifdef MKREPRO_DATE
  static const char build[] = MKREPRO_TIME "/" MKREPRO_DATE;
#   else
  static const char build[] = __TIME__ "/" __DATE__;
#   endif
  static const char mlist[] = "JanFebMarAprMayJunJulAugSepOctNovDec";

  char  monstr[4];
  const char *  cp;
  unsigned short  hour, minute, second, day, year;
  /* Note: The above quantities are used for sscanf 'hu' format,
   * so using 'uint16_t' is contra-indicated!
   */

#   ifdef DEBUG
  static int        ignore  = 0;
#   endif

  ZERO(*jd);
  jd->year     = 1970;
  jd->month    = 1;
  jd->monthday = 1;

#   ifdef DEBUG
  /* check environment if build date should be ignored */
  if (0 == ignore) {
    const char * envstr;
    envstr = getenv("NTPD_IGNORE_BUILD_DATE");
    ignore = 1 + (envstr && (!*envstr || !strcasecmp(envstr, "yes")));
  }
  if (ignore > 1)
    return FALSE;
#   endif

  if (6 == sscanf(build, "%hu:%hu:%hu/%3s %hu %hu",
		  &hour, &minute, &second, monstr, &day, &year)) {
    cp = strstr(mlist, monstr);
    if (NULL != cp) {
      jd->year     = year;
      jd->month    = (uint8_t)((cp - mlist) / 3 + 1);
      jd->monthday = (uint8_t)day;
      jd->hour     = (uint8_t)hour;
      jd->minute   = (uint8_t)minute;
      jd->second   = (uint8_t)second;

      return TRUE;
    }
  }

  return FALSE;
}


/*
 *---------------------------------------------------------------------
 * basic calendar stuff
 *---------------------------------------------------------------------
 */

/* month table for a year starting with March,1st */
static const uint16_t shift_month_table[13] = {
  0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337, 366
};

/* month tables for years starting with January,1st; regular & leap */
static const uint16_t real_month_table[2][13] = {
  /* -*- table for regular years -*- */
  { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
  /* -*- table for leap years -*- */
  { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};







